package com.wstuo.itsm.request.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.wstuo.common.bpm.api.IBPI;
import com.wstuo.common.config.dictionary.dao.IDataDictionaryItemsDAO;
import com.wstuo.common.noticeRule.service.INoticeRuleService;
import com.wstuo.common.tools.dao.IUserReturnVisitDAO;
import com.wstuo.common.tools.dto.CostDTO;
import com.wstuo.common.tools.dto.UserReturnVisitDTO;
import com.wstuo.common.tools.entity.UserReturnVisit;
import com.wstuo.common.tools.service.ICostService;
import com.wstuo.common.tools.service.IUserReturnVisitService;
import com.wstuo.itsm.request.entity.Request;
import com.wstuo.itsm.request.dao.IRequestDAO;
import com.wstuo.itsm.request.dto.RequestDTO;
import com.wstuo.common.exception.ApplicationException;
import com.wstuo.common.jbpm.IJbpmFacade;
import com.wstuo.common.security.dao.IOrganizationDAO;
import com.wstuo.common.security.dao.IUserDAO;
import com.wstuo.common.security.entity.Organization;
import com.wstuo.common.security.entity.User;
import com.wstuo.common.security.utils.LanguageContent;
import com.wstuo.common.util.StringUtils;

/**
 * 请求动作Service类
 * 
 * @author WSTUO_QXY
 * 
 */
public class RequestActionService implements IRequestActionService {
	final static Logger LOGGER = Logger.getLogger(RequestActionService.class);
	@Autowired
	private IRequestDAO requestDAO;
	@Autowired
	private IUserDAO userDAO;
	@Autowired
	private IDataDictionaryItemsDAO dataDictionaryItemsDAO;
	@Autowired
	private IOrganizationDAO organizationDAO;
	@Autowired
	private IJbpmFacade jbpmFacade;
	@Autowired
	private IBPI bpi;
	@Autowired
	private IRequestService requestService;
	@Autowired
	private IUserReturnVisitService userReturnVisitService;
	@Autowired
	private ICostService costService;
	@Autowired
	private IUserReturnVisitDAO userReturnVisitDAO;
	/**
	 * 请求指派
	 * 
	 * @param requestDTO
	 */
	@Transactional
	public void requestAssgin(RequestDTO requestDTO) {
		Request request = requestDAO.findById(requestDTO.getEno(), null);
		//String assignee = null;
		//String assigneeGroup = null;
		// 指派技术员
		if (requestDTO.getAssigneeNo() != null) {
			User user = userDAO.findById(requestDTO.getAssigneeNo());
			if(user!=null){
				request.setTechnician(user);
				//assignee = user.getLoginName();
			}
		} else {
			request.setTechnician(null);
		}
		// 指派组
		if (requestDTO.getAssigneeGroupNo() != null) {
			Organization org = organizationDAO.findById(requestDTO
					.getAssigneeGroupNo());
			request.setAssigneeGroup(org);
			//assigneeGroup = "Group_" + org.getOrgNo();
		} else {
			request.setAssigneeGroup(null);
		}
		/*if(request.getPid()!=null){
			bpi.assignTaskByPid(requestDTO.getPid(), assignee);
			bpi.addTaskParticipatingGroupByPid(requestDTO.getPid(), assigneeGroup);
		}*/
		requestDAO.merge(request);
		// 请求指派通知
		requestService.requestProcessNotice(INoticeRuleService.REQUEST_ASSIGN_NOTICE, request,
				null, null, null, requestDTO.getCurrentUser(), null, null);

	}

	

	/**
	 * 请求提取
	 * 
	 * @param requestDTO
	 */
	@Transactional
	public void requestGet(RequestDTO requestDTO) {
		Request request = requestDAO.findById(requestDTO.getEno());
		if (requestDTO.getCurrentUser() != null) {
			User user = userDAO.findUniqueBy("loginName",requestDTO.getCurrentUser());
			request.setTechnician(user);
		}
		/*if(request.getPid()!=null){
			bpi.assignTaskByPid(requestDTO.getPid(),requestDTO.getCurrentUser());
		}*/
		requestDTO.setEno(request.getEno());
		requestDTO.setPid(request.getPid());
		requestDAO.merge(request);

	}

	/**
	 * 请求再指派
	 * @param requestDTO
	 */
	@Transactional
	public void requestAgainAssgin(RequestDTO requestDTO) {
		Request request = requestDAO.findById(requestDTO.getEno());
		User user = null;
		if (requestDTO.getAssigneeNo() != null) {
			user = userDAO.findById(requestDTO.getAssigneeNo());
			request.setTechnician(user);
		}
		/*if(request.getPid()!=null){
			// task分配人设置
			this.assignTask(requestDTO.getPid(), user.getLoginName());
		}*/
		requestDAO.merge(request);
		requestService.requestProcessNotice(INoticeRuleService.REQUEST_ASSIGN_NOTICE, request,
				null, null, null, requestDTO.getCurrentUser(), null, null);
	}


	/**
	 * 请求升级
	 * 
	 * @param requestDTO
	 */
	@Transactional
	public void requestUpgrade(RequestDTO requestDTO) {
		Request request = requestDAO.findById(requestDTO.getEno(), null);
		// 升级到，设置为负责人
		// 升级完毕
		request.setUpgradeApplySign(IRequestService.REQUEST_UPGRADEAPPLY_SIGN);
		request.setEventCode(requestDTO.getRequestCode());
		if (requestDTO.getOwnerNo() != null) {
			User user = userDAO.findById(requestDTO.getOwnerNo());
			List<User> list = new ArrayList<User>();
			if (user != null) {
				request.setOwner(user);
				list.add(user);
			}
			requestService.requestProcessNotice(INoticeRuleService.REQUEST_UPGRADE_NOTICE,
					request, null, list, null, requestDTO.getCurrentUser(),
					null, null);

			requestDAO.merge(request);
		}

	}


	/**
	 * 请求回访
	 * 
	 * @param requestDTO
	 */
	@Transactional
	public void requestVisit(RequestDTO requestDTO) {
		Request request = requestDAO.findById(requestDTO.getEno(), null);
		User user = request.getCreatedBy();
		User technician = request.getTechnician();
		if ("requestVisit".equals(requestDTO.getOptType())) {
			// 保存回访记录
			UserReturnVisitDTO userReturnVisitDTO = new UserReturnVisitDTO();
			userReturnVisitDTO.setReturnVisitSubmitTime(new Date());
			userReturnVisitDTO
					.setReturnVisitUser(requestDTO.getCreatedByName());
			userReturnVisitDTO.setReturnVisitSubmitUser(requestDTO
					.getCreatedByName());
			userReturnVisitDTO.setEntityType("itsm.request");
			userReturnVisitDTO.setEno(requestDTO.getEno());
			if(technician != null){
				userReturnVisitDTO.setReturnVisitTechnicianName(technician.getLoginName());
			}
			userReturnVisitService.saveUserReturnVisit(userReturnVisitDTO);
			request.setVisitRecord(userReturnVisitDTO.getVisitId().toString());
			List<String> userList = new ArrayList<String>();
			if (user != null) {
				userList.add(user.getLoginName());
			}
			requestService.requestProcessNotice(INoticeRuleService.REQUEST_VISIT_NOTICE, request,
					userList, null, requestDTO.getVisitPath(),
					requestDTO.getCurrentUser(), null, null);
		} else {
			if (user != null) {
				UserReturnVisit urv = userReturnVisitDAO.findUniqueBy("eno",
						requestDTO.getEno());
				if (urv == null) {
					UserReturnVisitDTO userReturnVisitDTO = new UserReturnVisitDTO();
					userReturnVisitDTO.setReturnVisitSubmitTime(new Date());
					userReturnVisitDTO.setReturnVisitUser(requestDTO
							.getCreatedByName());
					userReturnVisitDTO.setReturnVisitSubmitUser(requestDTO
							.getCreatedByName());
					userReturnVisitDTO.setEntityType("itsm.request");
					userReturnVisitDTO.setEno(requestDTO.getEno());
					if(technician != null){
						userReturnVisitDTO.setReturnVisitTechnicianName(technician.getLoginName());
					}
					userReturnVisitService
							.saveUserReturnVisit(userReturnVisitDTO);
					request.setVisitRecord(userReturnVisitDTO.getVisitId()
							.toString());
				}
				List<String> userList = new ArrayList<String>();
				userList.add(user.getLoginName());
				requestService.requestProcessNotice(INoticeRuleService.REQUEST_VISIT_NOTICE,
						request, userList, null, requestDTO.getVisitPath(),
						requestDTO.getCurrentUser(), null, null);
			}
		}
		requestDAO.merge(request);
	}


	/**
	 * 根据PID重新设置task分配人
	 * 
	 * @param pid
	 * @param userName
	 *//*
	@Transactional
	private void assignTask(String pid, String userName) {
		ProcessInstance pi = jbpmFacade.getInstanceById(pid);
		String nextActivityName = jbpmFacade.getActivityNamesByInstance(pi)
				.iterator().next();
		String taskId = jbpmFacade.getTaskId(pid, nextActivityName);
		jbpmFacade.assignTask(taskId, userName);
	}*/

	/**
	 * 自助解决请求直接关闭,不管处于流程那一步，请求直接关闭
	 * 
	 * @param requestDTO
	 */
	@Transactional
	public void requestDirectClose(RequestDTO requestDTO) {
		Request request = requestDAO.findById(requestDTO.getEno(), null);
		if(StringUtils.hasText(requestDTO.getPid()) && request.getFlowStart()){
			bpi.endProcessInstance(requestDTO.getPid());
		}
		// 响应时间
		if (request.getResponsesTime() == null) {
			request.setResponsesTime(new Date());
		}
		// 完成时间
		request.setRequestResolvedTime(new Date());

		request.setIsFCR(true);
		request.setStatus(dataDictionaryItemsDAO.findUniqueBy("dno","request_close"));
		if (request.getStatus() == null){
			throw new ApplicationException("ERROR_REQUEST_STATUS_IS_NULL");
		}

		// //关闭时间
		request.setCloseTime(new Date());
		LanguageContent lc = LanguageContent.getInstance();
		if("requestDirectClose".equals(requestDTO.getOptType()))
			request.setCloseCode(lc.getContent("label.request.self.help.resolve"));
		else{
			request.setCloseCode(lc.getContent("lable.requestBatchClose"));
		}
		if (request.getSolutions() != null) {
			request.setSolutions(request.getSolutions()+ requestDTO.getSolutions());
		} else {
			request.setSolutions(requestDTO.getSolutions());
		}
		// SLA状态
		String slaStatus = requestService.getSlaStatus(request);
		request.setSlaState(dataDictionaryItemsDAO.findUniqueBy("dno",
				slaStatus));

		requestDAO.merge(request);

		// 请求关闭通知
		requestService.requestProcessNotice(INoticeRuleService.REQUEST_CLOSE_NOTICE, request,
				null, null, requestDTO.getVisitPath(),requestDTO.getCurrentUser(), null, null);
		if("requestDirectClose".equals(requestDTO.getOptType()))
			// 请求自助解决通知
			requestService.requestProcessNotice(INoticeRuleService.REQUEST_SELF_SOLVE_NOTICE, request,
					null, null, requestDTO.getVisitPath(),requestDTO.getCurrentUser(), null, null);
	}

	/**
	 * 请求挂起与解挂
	 * 
	 * @param requestDTO
	 */
	@Transactional
	public void requestHangRemove(RequestDTO requestDTO) {
		Request request = requestDAO.findById(requestDTO.getEno(), null);
		request.setHang(requestDTO.getHang());
		if (requestDTO.getHang()) {// 如果是挂起，请求状态改成挂起
			// 记录挂起前的请求状态
			request.setRemarkStatus(request.getStatus());
			request.setStatus(dataDictionaryItemsDAO.findUniqueBy("dno",
					"request_awaiting"));
			// 设置挂起时间
			request.setHangTime(new Date());
			// 把SLA状态修改成挂起
			request.setSlaState(dataDictionaryItemsDAO.findUniqueBy("dno",
					"RequestGetPending"));
			request.setMaxResponseTime(null);
			request.setMaxCompleteTime(null);
			// 请求挂起通知
			requestService.requestProcessNotice(INoticeRuleService.REQUEST_HANG_NOTICE, request,
					null, null, requestDTO.getVisitPath(),
					requestDTO.getCurrentUser(), null, null);

		} else {// 如果解挂就挂起前的请求状态
			request.setStatus(request.getRemarkStatus());
			// 保存进展及成本
			saveCost(request.getHangTime(), requestDTO.getCurrentUser(), request.getEno());
			// 解决挂起重新计算SLA
			requestService.removePendingReCalcRequestSLATime(request.getEno(),
					request.getHangTime(), new Date());

			// 解除挂起时间
			request.setHangTime(null);
			String slaStatus = requestService.getSlaStatus(request);
			request.setSlaState(dataDictionaryItemsDAO.findUniqueBy("dno",
					slaStatus));
			// 请求解除挂起通知
			requestService.requestProcessNotice(INoticeRuleService.REQUEST_REMOVE_HANG_NOTICE,
					request, null, null, requestDTO.getVisitPath(),
					requestDTO.getCurrentUser(), null, null);

		}
		requestDAO.merge(request);
	}
	/**
	 * 保存进展及成本
	 * @param hangTime
	 * @param CurrentUserName
	 * @param eno
	 */
	private void saveCost(Date hangTime,String currentUserName,Long eno){
		CostDTO costDTO = new CostDTO();
		// 保存进展及成本
		Date start = hangTime;
		Date end = new Date();
		User user = userDAO.findUniqueBy("loginName",
				currentUserName);
		if (user != null){
			costDTO.setUserId(user.getUserId());
		}
		costDTO.setStartTime(start);
		costDTO.setEndTime(end);
		costDTO.setStartToEedTime((end.getTime() - start.getTime()) / 1000 / 60);
		costDTO.setActualTime((end.getTime() - start.getTime()) / 1000 / 60);
		costDTO.setType("HANG");
		costDTO.setEno(eno);
		costDTO.setEventType("itsm.request");
		costDTO.setStatus(2L);
		costDTO.setStage("AWAITING CUSTOMER RESPONSE");
		costService.saveCost(costDTO);
	}

	/**
	 * 修改SLA响应与完成时间
	 * (功能已注释)
	 * @param requestDTO
	 */
	@Transactional
	public void editRequestSlaTime(RequestDTO requestDTO) {
		Request request = requestDAO.findById(requestDTO.getEno(), null);
		request.setMaxResponseTime(requestDTO.getRequestResponseTime()
				.getTime());
		request.setMaxCompleteTime(requestDTO.getRequestCompleteTime()
				.getTime());
		// SLA状态
		String slaStatus = requestService.getSlaStatus(request);
		request.setSlaState(dataDictionaryItemsDAO.findUniqueBy("dno",
				slaStatus));
		requestDAO.merge(request);
	}

}
